import sys
import os

import redis
import aiomysql
import asyncio
import aioredis
import logging
import logging.handlers
from tornado import web
from tornado import options
from tornado_swagger.setup import setup_swagger

from views import index, user, shopping_cart, order, address, good_sku_detail, goods_category, history_record, \
    goods_collect,pay

from configs import config
from views.demo import DemoHandler
from utils import sessions


class Application(web.Application):
    routes = [
        # 首页
        web.url(r'/index/slider', index.IndexAdvertisement),
        web.url(r'/index/banner', index.IndexBanner),
        web.url(r'/index/recommend', index.IndexShowGood),
        web.url(r'/index/hot', index.IndexShowGood),
        web.url(r'/index/boutique', index.IndexShowGood),
        # web.url(r'/index/category_icon', index.HomeCategoryIcon),

        # 商品分类
        web.url(r'/goods/category/recommend', goods_category.CategoryRecommend),
        web.url(r'/goods/category/good/(?P<id>\w+)', goods_category.CategoryGood),
        # web.url(r'/goods/second_category/good/(?P<id>\w+)', goods_category.SecondCategoryGood),
        #
        # 购物车
        web.url(r'/shopping_cart', shopping_cart.ShoppingCart),

        # web.url(r'/add_to_cart', shopping_cart.AddToCart),
        web.url(r'/shopping_cart/is_selected_all', shopping_cart.CartIsSelectedAll),
        web.url(r'/delete_cart', shopping_cart.DeleteCart),
        web.url(r'/put_cart', shopping_cart.PutCart),

        # 商品good_sku详情
        web.url(r'/good_detail/(?P<id>\w+)', good_sku_detail.GoodDetail),

        # 足迹
        web.url(r'/history_record', history_record.HistoryRecord),
        web.url(r'/delete_record', history_record.DeleteRecord),

        # 商品收藏
        web.url(r'/goods_collect', goods_collect.GoodsCollect),
        web.url(r'/goods_delete_collect', goods_collect.DeleteCollect),

        # 订单结算
        web.url(r'/order_settlement', order.OrderSettlement),
        web.url(r'/now_buy', order.NowBuy),

        # 我的订单
        web.url(r'/order/my_order[/]{0,1}(?P<order_status>-?\d*)', order.MyOrder),

        # 订单详情
        web.url(r'/order/detail', order.OrderDetail),

        # 提交订单
        web.url(r'/commit_order_by_cart', order.CommitOrderByCart, name='commit_order_by_cart'),
        web.url(r'/commit_order_by_spu', order.CommitOrderBySpu, name='commit_order_by_spu'),

        # 测试
        web.url(r"/test/(?P<name>\w+)", DemoHandler),

        # 注册
        web.url(r"/sms_register/(?P<mobile>\d{11})", user.SMSRegister),
        # 登录
        web.url(r"/sms_login/(?P<mobile>\d{11})", user.SMSLogin),
        web.url(r"/login_thirdparty", user.UserLoginThirdParty),
        web.url(r"/login", user.PasswordLogin),

        # 密码
        web.url(r"/password", user.Password),
        web.url(r"/alter_password", user.LoginPasswordModify),

        # 地址管理
        web.url(r"/address", address.AddressHandler),  # 创建地址
        web.url(r"/default_address", address.DefaultAddressHandler),  # 创建地址

        # 用户信息
        web.url(r"/user_info", user.UserInfoHandler),

        #
        web.url(r"/pay",pay.GenPayLinkHandler),

        #
        web.url(r"/demo",DemoHandler)

    ]

    @staticmethod
    def _init_db_():
        async def get_mysql_pool():
            return await aiomysql.create_pool(host=config.MYSQL_HOST, port=config.MYSQL_PORT, user=config.MYSQL_USER,
                                              password=config.MYSQL_PASSWD,
                                              db=config.MYSQL_DB,
                                              loop=asyncio.get_event_loop(), autocommit=False,
                                              maxsize=config.MYSQL_CONNECTION_MAXSIZE,
                                              pool_recycle=config.MYSQL_POOL_RECYCLE)

        async def get_redis_pool():
            return await aioredis.create_redis_pool(config.REDIS_ADDR,password=config.REDIS_PASSWORD, encoding='utf-8')


        task = [
            asyncio.ensure_future(get_mysql_pool()),
            asyncio.ensure_future(get_redis_pool())
        ]
        loop = asyncio.get_event_loop()
        loop.run_until_complete(asyncio.wait(task))
        pool, redis = [t.result() for t in task]
        config.pool = pool
        config.redis = redis

    def _init_logger(self):
        # logging.getLogger('tornado.access').disabled = True

        self.logger = logging.getLogger(options.options.app)
        self.logger.propagate = False
        log_dir = os.path.join(config.BASE_DIRS, 'log')

        if not os.path.exists(log_dir):
            os.mkdir(log_dir)
        log_file = os.path.join(log_dir, options.options.app)
        hdlr = logging.handlers.TimedRotatingFileHandler(log_file, when='D', interval=1, backupCount=40)
        formatter = logging.Formatter(config.LOGGING_FORMAT)
        hdlr.setFormatter(formatter)
        self.logger.addHandler(hdlr)

        stream_hdlr = logging.StreamHandler(sys.stdout)
        stream_hdlr.setFormatter(formatter)
        self.logger.addHandler(stream_hdlr)
        self.logger.setLevel(config.LOGGING_LEVEL)
        config.logger = self.logger

    def _init_session_(self):
        pool = redis.ConnectionPool(host=config.SESSION_REDIS_HOST,password=config.REDIS_PASSWORD, max_connections=10, decode_responses=True)
        config.sync_redis = redis.StrictRedis(connection_pool=pool)
        self.session_manager = sessions.SessionManager(config.SESSION_SECRET, config.sync_redis, config.SESSION_TIMEOUT)

    def __init__(self):
        self._init_db_()
        self._init_logger()
        self._init_session_()

        setup_swagger(
            self.routes,
            swagger_url="/doc",
            description="",
            api_version="1.0.0",
            title="Journal API",
            contact=dict(name="test", email="test@domain.com", url="https://www.cluas.me"),
        )
        # tornado-rest-swagger sdk Bug
        self.routes.append(
            web.url(r"/content/(.*)", web.StaticFileHandler, {"path": os.path.join(config.BASE_DIRS, "static")}))
        super(Application, self).__init__(self.routes, **config.settings)
